package com.itheima.stock.service.impl;

import com.google.common.base.Strings;
import com.itheima.stock.common.enums.ResponseCode;
import com.itheima.stock.mapper.SysUserMapper;
import com.itheima.stock.pojo.SysPermission;
import com.itheima.stock.pojo.SysUser;
import com.itheima.stock.service.PermissionService;
import com.itheima.stock.service.UserService;
import com.itheima.stock.utils.IdWorker;
import com.itheima.stock.vo.*;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;//加密解密对象

    @Autowired
    private PermissionService permissionService;

    @Override
    public R<LoginRespVo> login(LoginReqVo vo) {
        //数据错误
        if (vo==null || Strings.isNullOrEmpty(vo.getUsername()) || Strings.isNullOrEmpty(vo.getPassword())|| Strings.isNullOrEmpty(vo.getRkey())){
            return R.error(ResponseCode.DATA_ERROR.getMessage());
        }
        //验证码校验
        //获取redis中rkey对应的code验证码
        String rCode = (String) redisTemplate.opsForValue().get(vo.getRkey());
        //校验
        if (Strings.isNullOrEmpty(rCode) || !rCode.equals(vo.getCode())) {
            return R.error(ResponseCode.DATA_ERROR.getMessage());
        }
        //redis清除key
        redisTemplate.delete(vo.getRkey());
        //根据用户名查询用户信息
        SysUser user =sysUserMapper.findByUserName(vo.getUsername());
        //判断用户是否存在，存在则密码校验比对
        if(user==null||!passwordEncoder.matches(vo.getPassword(),user.getPassword())){
            return R.error(ResponseCode.SYSTEM_PASSWORD_ERROR.getMessage());
        }
        //组装登录成功数据
        LoginRespVo respVo = new LoginRespVo();
        //属性名称与类型必须相同，否则copy不到
        BeanUtils.copyProperties(user,respVo);
        //组装权限树
        //获取指定用户的权限集合
        List<SysPermission> permissions = permissionService.getPermissionByUserId(user.getId());
        //获取树状权限菜单数据
        List<PermissionRespNodeVo> tree=permissionService.getTree(permissions, "0", true);
        //获取菜单按钮集合
        List<String> authBtnPerms = permissions.stream().filter(per -> !Strings.isNullOrEmpty(per.getCode()) && per.getType() == 3).map(per -> per.getCode()).collect(Collectors.toList());
        respVo.setMenus(tree);
        respVo.setPermissions(authBtnPerms);
        System.out.println("登陆成功");
        return R.ok(respVo);
    }

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 分布式环境保证生成id唯一
     */
    @Autowired
    private IdWorker idWorker;

    /**
     * 生成验证码
     *  map结构：
     *      code： xxx,
     *      rkey: xxx
     * @return
     */
    @Override
    public R<Map> generateCaptcha() {
        //1.随机生成4位数字验证码
        String checkCode = RandomStringUtils.randomNumeric(4);

        //2.获取全局唯一id，转化：Long ——> String
        String rkey=String.valueOf(idWorker.nextId());

        //验证码存入redis中，并设置有效期1分钟
        redisTemplate.opsForValue().set(rkey,checkCode,60, TimeUnit.SECONDS);

        //3.组装数据
        HashMap<String, String> map = new HashMap<>();
        map.put("rkey",rkey);
        map.put("code",checkCode);
        return R.ok(map);
    }

    /**
     * id查询用户信息
     *
     * @param id
     * @return
     */
    @Override
    public R<UserRespVo> selUserById(Long id) {
        UserRespVo info = sysUserMapper.selUserById(id);
        return R.ok(info);
    }
}
